from rest_framework import serializers
from xiejian_user.models import User

class BookInfoModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

"""
serializer 序列化器的作用

序列化
    将对象转化成字典数据
反序列化
    先验证接收数据的合理性
    将json数据通过模型进行保存
    

将对象转化成字典数据
book=BookInfo.objects.get(id=1)

序列化器(book)
字典数据 = 序列化器转换

如何定义一个序列化器 和模型类定义很相似
class 序列化器(serializer.Serializer):
    字段 = serializer.类型(选项)
    
字段:     暂时记住 序列化器的字段名和模型名一样
类型:     暂时记住 序列化器的类型和模型一样
选项:     暂时不学
"""

from rest_framework import serializers

class UserInfoSerializer(serializers.Serializer):
    """个人数据序列化器"""
    mobile = serializers.CharField(required=True)
    avatar = serializers.ImageField(required=False,default="")
    real_name = serializers.DateField(write_only=True)
    id_card = serializers.IntegerField(required=False,min_value=1,max_value=100)

    """验证单独属性条件,函数名固定 validate_字段():"""
    # def validate_name(self,value):
    #     pass
    # def validate_pub_date(self,value):
    #     pass

    def validate_readcount(self, value):
        # value 就是指 当前字段所对应的值
        if value < 0:
            # raise Exception('阅读数不能为负数')
            # 可以使用 drf 的异常
            raise serializers.ValidationError('阅读数不能为负数')
        # 一定要记得 返回value
        return value

    """验证多个属性条件,函数名固定 validate():"""
    # def validate(self, data):
    def validate(self, attrs):
        # attrs 暂时理解为 data
        # attrs = {}
        readcount = attrs.get('readcount')
        commentcount = attrs['commentcount']

        if commentcount > readcount:
            raise serializers.ValidationError('评论量不能大于阅读量')

        # 一定要记得返回
        return attrs

    # 如果您的对象实例与Django模型相对应，则还需要确保这些方法将对象保存到数据库中
    def create(self, validated_data):
        # validated_data
        # 验证没有问题的数据
        # 如果我们的data没有问题,则 validated_data = data

        return BookInfo.objects.create(**validated_data)

    # 默认序列化器 是不会给我们提供 隐藏的 管理模型类名小写_set
    # peopleinfo_set = [1,2,3,4,5]
    # 因为 是列表
    # 书籍和人物是 1:n

    # PrimaryKeyRelatedField        read_only=True
    # or
    # PrimaryKeyRelatedField         query_set
    peopleinfo_set = serializers.PrimaryKeyRelatedField(many=True,read_only=True)
    """
    {'id': 1, 'name': '射雕英雄传', 'peopleinfo_set': [1, 2, 3, 4, 5]}
    """


"""
字典是如何生成的呢? {key:value}
key 来源于 我们序列化器中定义的字段名
value 来源于 我们的模型所对应的数据库的数据
"""


class PeopleInfoSerializer(serializers.Serializer):
    """英雄数据序列化器"""
    GENDER_CHOICES = (
        (0, 'male'),
        (1, 'female')
    )
    id = serializers.IntegerField(label='ID')
    name = serializers.CharField(label='名字')
    gender = serializers.ChoiceField(choices=GENDER_CHOICES, label='性别')
    description = serializers.CharField(label='描述信息')

    """主要就是讲解外键 外键特殊"""
    # IntegerField --> book_id
    # book_id = 1 值
    """第一种"""
    # book_id = serializers.IntegerField()

    # 如果想写 book 必须按照文档中的 字段类型来,不能使用 IntegerField
    # book = BookInfo() 对象
    # book = serializers.IntegerField() # 错误的

    # 关系必须显式设置queryset或set read_only=True
    # Relational field must provide a `queryset` argument,
    # override `get_queryset`, or set read_only=`True`.

    # read_only=True 后边讲
    """第二种"""
    # book = serializers.PrimaryKeyRelatedField(read_only=True)

    # queryset 查询结果集 我们只要把书籍的模型数据都给它 就可以了
    """第三种"""
    # book = serializers.PrimaryKeyRelatedField(queryset=BookInfo.objects.all())

    # {'id': 1, 'name': '郭靖', 'gender': 1, 'description': '降龙十八掌', 'book': 1}

    # 需求 之前是获取外键id值
################################################################################################
    """现在的需求是 获取外键所关联的 书籍name"""
    # StringRelatedField 会获取 它所关联的模型的 __str__ 方法返回的内容
    # book = serializers.StringRelatedField()

    # 1个值
    # 需求是: 想获取 book 所对应的 模型的很多字典数据
    # book
    # book(1) = BookInfoSerializer(instance=book(2))
    # 第一个book是 序列化器的book
    # 第二个book是 模型的book

    # BookInfoSerializer 它可以将 对象转换为字典数据
    # book = {'id':xxx,'name":xxxx}
    # BookInfoSerializer 的本质 Field
    # 序列化器嵌套序列化器
    # 字典嵌套字典
    # 试试效果就出来了
    """第四种"""
    # book = BookInfoSerializer()

    """
    预估的{'id': 1, 'name': '郭靖', 'book': {'id':xxx,'name":xxxx}}
    实际的
    {'id': 1, 'name': '郭靖', 'book': OrderedDict([('id', 1), ('name','射雕英雄传'), ('pub_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34)])}
    """


"""
# 序列化器A
class TrackSerializer(serializers.ModelSerializer):
    class Meta:
        model = Track
        fields = ['order', 'title', 'duration']
#序列化器B
class AlbumSerializer(serializers.ModelSerializer):
    # 序列化器A
    tracks = TrackSerializer(many=True, read_only=True)

    class Meta:
        model = Album
        fields = ['album_name', 'artist', 'tracks']
"""